#! /usr/bin/env python
# -*- coding: UTF-8 -*-

# Copyright (C) 2008 Rylov Roman <roman@rylov.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import gnome,gnome.ui
import gnomeapplet
import sys,re,os
import gtk.glade as glade

#import PreferencesDialog1

import logging
from datetime import datetime

ADDRES = "addres"
TIMEOUT = "timeout"
TEXT = "text"
values = {ADDRES : '172.16.0.1', TIMEOUT : 6000, TEXT: 0}
configFileName = os.path.expanduser("~/.knockknock");
  
logging.basicConfig(filename="/tmp/applet.log") # сохранение в лог
log = logging.getLogger("KnockKnock")
log.setLevel(logging.INFO)

class PreferencesDialog(gobject.GObject):
                    
    def __init__(self, glade_file_name, name_validator_func, presets_store, preset_display_func):
        gobject.GObject.__init__(self)
        
        #self._valid_name_func = name_validator_func;
        self._presets_store = presets_store
        #self._preset_display_func = preset_display_func
        
        glade_widgets = glade.XML(glade_file_name, 'dialog1')
        self._dialog = glade_widgets.get_widget('dialog1')
	self.preferences = self._dialog
        glade_widgets.signal_autoconnect(self)
        self._ok_button = glade_widgets.get_widget('ok_button')
	self._cancel_button = glade_widgets.get_widget('cancel_button')
	
	self._ip = glade_widgets.get_widget('ip_entry')
	self._timeout = glade_widgets.get_widget('timeout')
	self._image = glade_widgets.get_widget('radiobutton1')

	self._ip.set_text(self._presets_store[ADDRES])
	self._timeout.set_value(int(self._presets_store[TIMEOUT]))
	self._image.set_active(int(self._presets_store[TEXT]))
	
        self._ok_button.connect('clicked', self._on_save_button_clicked)
        self._cancel_button.connect('clicked', self._on_cancel_button_clicked)
       
    def show(self):
	self._dialog.present()   
	
    def hide(self):
        self._dialog.hide()
        
    def get_preset(self):
	values = {ADDRES : self._ip.get_text(), TIMEOUT : int(self._timeout.get_value()), TEXT: self._image.state}
        return values
          
    def _on_save_button_clicked(self, button):
	print "On_save_button_clicked"
	values = {ADDRES : self._ip.get_text(), TIMEOUT : int(self._timeout.get_value()), TEXT: self._image.state}
	saveConfigFile(configFileName, values)
	self._dialog.hide()
	
    def _on_cancel_button_clicked(self,button):
	print "On_cancel_button_clicked"
	self._dialog.hide()


class KnockKnockApplet(gnomeapplet.Applet):# основной класс
 def update_tooltip(self, text = None):
    if text is None:
        self.tooltip.set_tip(self.applet, self.tooltip_text)
    else:
        self.tooltip_text = text
        self.update_tooltip()
    
 def update_text(self,text=None):
    if text is None:
        self.temp.set_text(self.data)
    else:
        self.data = text
        self.update_text()

 def update_image(self,image_path=None):
    if image_path is None:
        self.itemp.set_from_file(self.idata)
    else:
        self.idata = image_path
        self.update_image()
 def load_conf(self):
    # Load the config file.
    try:
	values = loadConfigFile(configFileName)
    except IOError, e:
	print "IOError on load: ", e
	saveConfigFile(configFileName, values)
    self._timeout = int(values[TIMEOUT])
    self._url = values[ADDRES]
    self.stat = int(values[TEXT])
    
 def create_applet(self):    # создание апплета, самая смыслонагруженная часть
    
    app_window = self.applet
    event_box = gtk.EventBox()
    #event_box.set_events(gtk.gdk.BUTTON_PRESS_MASK |
      #  gtk.gdk.POINTER_MOTION_MASK |
      #  gtk.gdk.POINTER_MOTION_HINT_MASK |
       # gtk.gdk.CONFIGURE )
    self.load_conf()
    self._ok_image = "/usr/share/gnome-panel/pixmaps/Knock_KnockApplet/ok.png"
    self._not_image = "/usr/share/gnome-panel/pixmaps/Knock_KnockApplet/not.png"
    self._name = "Knock knock"
    self._description = "Knock knock Applet"
    #self._timeout = int(values[TIMEOUT])
    #self._url = values[ADDRES]
    #self.stat = int(values[TEXT])
    self._lifeline = re.compile(r"(\d) received") 
    self._check = False
    
    self.stat = True # True - Image; False  - Text
    self.inside_applet = gtk.HBox()
    self.init_ppmenu()
   
    if self.stat : 
       self.itemp = gtk.Image()
       self.idata = self._not_image 
       self.update_image()
       self.inside_applet.pack_start(self.itemp)
    else: 
       self.temp = gtk.Label()
       self.data = "TT" # я не стал искать иконку и ограничился надписью TT
       self.update_text()
       self.inside_applet.pack_start(self.temp)
 
    self.tooltip = gtk.Tooltips() # в качестве демонстрации, создадим также всплывающую подсказку
    self.tooltip_text = "Middle click for tooltip update"
    self.update_tooltip()
    
    event_box.add(self.inside_applet)
    app_window.add(event_box)
    app_window.show_all()
    gobject.timeout_add(self._timeout, self.on_timeout)
    self._pref_dialog = PreferencesDialog("./ui/knockknock_preferences_form.glade","tst1",values,"tst3")
    return event_box

 def button_pressed(self, widget, event, *args, **kwargs):
    if event.button==3:# Правая показать меню
        log.info("CLICK button 3")
        self._show_ppmenu()
    elif event.button==2:# средняя кнопка мыши, обновить подсказку
        self.update_tooltip(datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S"))
        self.update_image(self._ok_image)
    elif event.button==1:# левая кнопка мыши, записать в лог
        log.info("Button Pressed: %s",datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S"))
        self.update_image(self._not_image)

 def init_ppmenu(self):
    """Create popup menu"""
    self.ppmenu_xml = """
		<popup name="button3">
		<menuitem verb="Параметры" pixtype="stock" pixname="gtk-properties" name="Preferences Item" _label="_Preferences"/>
		<menuitem name="About Item" verb="About" stockid="gtk-about" />
		</popup>
	"""
    self.ppmenu_verbs = [
    ('Параметры',  self.on_ppm_pref),
	("About", self.on_ppm_about),	
    ]
        #~('Параметры', lambda component, verb:  self._pref_dialog.show()),
	
    
 def _show_ppmenu(self):
    """Show popup menu"""
    self.applet.setup_menu(self.ppmenu_xml, self.ppmenu_verbs, None)

 def on_ppm_about(self, event, data=None):
    """Action on choosing 'about' in popup menu"""
    gnome.ui.About("GNOME Knock Knock Applet", "0.1", "GNU General Public License v.2",
                    "Simple applet for Python powered GNOME applet",
                    ["Rylov Roman <roman@rylov.com>",]
                   ).show()
 def on_ppm_pref(self,event, data=None):
	self._pref_dialog.show() #self._pref_dialog.show()
	self._check = True
	 
 def on_timeout(self):
		import os
		pingaling = os.popen("ping -q -c2 "+self._url,"r")
		status =-1
		while 1:
			line = pingaling.readline()
		#	print line
			if not line: break
			igot = re.findall(self._lifeline,line)
			if igot:
				status = int(igot[0]) #Nubmer of received packages
		if (status == 2):
				self.update_image(self._ok_image)
		else:
				self.update_image(self._not_image)
		if self._check: 
			self.load_conf()
			self._check = False
		return True

 def __init__(self,applet,iid):
    self.__gobject_init__()
    self.applet = applet

    self.box = self.create_applet()
    self.applet.connect("button-press-event",self.button_pressed) # добавляем обработчик события клика
    self.button_actions = {
        1: lambda: None,
        2: lambda: None,
        3: self._show_ppmenu,
    }
    log.info("Applet created succesfully")

 # load the configuration file
def loadConfigFile(fileName):
		configFile = open(fileName)
		# Read the contents into a hash
		values = {}
		line = configFile.readline()
		while (line != ""):
			line = str.strip(line)
			(key, value) = str.split(line, "=", 1)
			values[key] = value		
			line = configFile.readline()
		configFile.close()
		return values

	# Save the configuration file
def saveConfigFile(fileName, values):
		configFile = open(fileName, "w")
		for key in values.keys():
			configFile.write(str(key) + "=" + str(values[key]) + "\n")
		configFile.close()
	
gobject.type_register(KnockKnockApplet)

DEBUG = False

def knockknock_applet_factory(applet, iid): # Реализация фабрики
	log.info("Creating the applet...")
	KnockKnockApplet(applet, iid)
	return True

log.info("Starting...")
if __name__ == '__main__':
    gobject.type_register(KnockKnockApplet)

    # Use parameter "run-in-window" to just run as a regular
    # application for debugging purposes
    if len(sys.argv) > 1 and sys.argv[1] == '-d':
        # create the main window
        main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        main_window.set_title("Hello")
        main_window.connect('destroy', gtk.main_quit)
        main_window.set_default_size(36, 36)

        # create the applet and run in the window
        app = gnomeapplet.Applet()
        knockknock_applet_factory(app, None)
        app.reparent(main_window)

        # run it
        main_window.show_all()
        gtk.main()
    else:
        # create as an applet
	gnomeapplet.bonobo_factory("OAFIID:Knock_KnockApplet_Factory",
                       KnockKnockApplet.__gtype__,
                       "KnockKnock",
                       "0.1",
                       knockknock_applet_factory) # Запуск всего механизма

log.info("Stopping...")
